from django.contrib import messages
from django.contrib.auth.mixins import (
    LoginRequiredMixin,
    PermissionRequiredMixin,
)
from django.shortcuts import render, redirect
from django.utils.translation import ugettext as _
from django.views.generic import ListView, TemplateView, View
from django.views.generic.base import ContextMixin
from django.utils import timezone

from common.constants import PERMS
from common.mixins import SidebarMixin, PageinatorMixin, UserCourseRelatedMixin
from user.contants import GROUP_TEACHER
from .forms import (
    UserForm, UserLimitedForm,
    WorkFormset, StudyFormset, ResumeFormset, HorizontalFormHelper,
)
from .models import User, EnrollmentHistory


class UserListView(PermissionRequiredMixin, SidebarMixin, ListView,
                   PageinatorMixin):
    template_name = 'user/list.html'
    model = User
    permission_required = (PERMS.IS_SUPERVISOR,)
    context_object_name = 'user_list'

    sort_f = "a"
    sort_f_value = ""

    @property
    def section_title(self):
        return 'User Management'

    @property
    def user_list_class(self):
        return 'active'

    @property
    def search_url(self):
        return 'user:list'

    def get_ordering(self):
        return '-' + 'date_joined'

    def get_queryset(self):
        queryset = super(UserListView, self).get_queryset(
        )

        #  sort_dict = {}
        #  sort_dict['username'] = self.request.GET.get('username')
        #  sort_dict['first_name'] = self.request.GET.get('first_name')
        #  sort_dict['last_name'] = self.request.GET.get('last_name')
        #  sort_dict['email'] = self.request.GET.get('email')

        #  for parm, parm_value in sort_dict.items():
        #      if parm_value == 'asc':
        #          queryset = queryset.order_by(parm)
        #          self.sort_f = parm
        #          self.sort_f_value = "asc"
        #          break
        #      if parm_value == 'dsc':
        #          queryset = queryset.order_by("-" + parm)
        #          self.sort_f = parm
        #          self.sort_f_value = "dsc"
        #          break
        #
        queryset = super(UserListView, self).filter_queryset(queryset)
        # print(queryset, queryset.object_list)

        return queryset

    def get_context_data(self, **kwargs):
        context = super(UserListView, self).get_context_data(**kwargs)
        q = self.request.GET.get('q')
        if q:
            context['q'] = q
        return context


class UserDeleteView(PermissionRequiredMixin, ContextMixin, View):

    permission_required = ('user.change_user')

    user = None

    def init(self, **kwargs):
        if 'pk' in kwargs:
            self.user = User.objects.get(id=kwargs['pk'])

    def post(self, request, *args, **kwargs):
        self.init(**kwargs)
        self.user.is_active = False
        self.user.save()
        return redirect('user:list')


class CreateOrUpdateUserView(PermissionRequiredMixin, SidebarMixin,
                             ContextMixin, View):

    permission_required = ('user.change_user',)

    # template used variables
    section_title = 'Create User'
    submit_text = 'Create'
    success_msg = 'Profile was successfully created!'

    user_form = None
    study_formset = None
    work_formset = None
    resume_formset = None
    form_helper = None

    user = None

    def init(self, **kwargs):
        if 'pk' in kwargs:
            self.user = User.objects.get(id=kwargs['pk'])
            self.section_title = 'User Management'
            self.user_list_class = 'active'
            self.submit_text = 'Update'
            self.success_msg = 'Profile was successfully created!'

    def get(self, request, *args, **kwargs):
        self.init(**kwargs)
        self.user_form = UserForm(instance=self.user)
        self.study_formset = StudyFormset(instance=self.user)
        self.work_formset = WorkFormset(instance=self.user)
        self.resume_formset = ResumeFormset(instance=self.user)
        self.form_helper = HorizontalFormHelper()

        return render(
            request, 'user/create_or_update.html',
            self.get_context_data(),
        )

    def post(self, request, *args, **kwargs):
        self.init(**kwargs)

        old_courses = []
        if self.user:
            old_courses = list(self.user.enrolling.all())

        self.user_form = UserForm(request.POST, instance=self.user)
        self.study_formset = StudyFormset(
            data=request.POST, instance=self.user)
        self.work_formset = WorkFormset(
            data=request.POST, instance=self.user)
        self.resume_formset = ResumeFormset(
            request.POST, request.FILES, instance=self.user)
        self.form_helper = HorizontalFormHelper()

        if (self.user_form.is_valid() and self.study_formset.is_valid() and
                self.work_formset.is_valid() and
                self.resume_formset.is_valid()):
            user = self.user_form.save()
            self.user_form.save_m2m()

            new_courses = list(user.enrolling.all())
            for old_course in old_courses:
                if old_course not in new_courses:
                    user.enrollment.filter(course=old_course).delete()
            for new_course in new_courses:
                if new_course not in old_courses:
                    enrollment = EnrollmentHistory.objects.create(
                        user=user, course=new_course,
                        date=timezone.now(),
                    )
                    enrollment.save()

            study_exps = self.study_formset.save(commit=False)
            for study_exp in study_exps:
                study_exp.user = user
                study_exp.save()
            for obj in self.study_formset.deleted_objects:
                obj.delete()

            work_exps = self.work_formset.save(commit=False)
            for work_exp in work_exps:
                work_exp.user = user
                work_exp.save()
            for obj in self.work_formset.deleted_objects:
                obj.delete()

            resumes = self.resume_formset.save(commit=False)
            for resume in resumes:
                resume.user = user
                resume.save()

            messages.success(request, _(self.success_msg))
            return redirect('user:list')
        else:
            return render(
                request, 'user/create_or_update.html',
                self.get_context_data(),
            )


class TeacherView(PermissionRequiredMixin, UserCourseRelatedMixin, TemplateView):
    permission_required = (PERMS.IS_TEACHER,)
    template_name = 'user/teacher.html'

    def dispatch(self, request, *args, **kwargs):
        self.course_slug = 'xx'
        return super(TeacherView, self).dispatch(request, *args, **kwargs)

    def get(self, request, *args, **kwargs):
        user = self.request.user
        courses = user.teaching.all()
        if courses:
            course = courses[0]
            return redirect('course:students', pk=course.pk)
        else:
            return super(TeacherView, self).get(request, *args, **kwargs)


class StudentView(PermissionRequiredMixin, SidebarMixin, TemplateView):
    permission_required = (PERMS.IS_STUDENT,)
    template_name = 'course/student/calendar.html'

    def get(self, request):
        user = self.request.user
        courses = user.enrolling.all()
        return self.render_to_response({
            'courses': courses,
        })


class ProfileView(UserCourseRelatedMixin, SidebarMixin, ContextMixin, View):

    def dispatch(self, request, *args, **kwargs):
        if request.user.current_group == GROUP_TEACHER:
            self.course_slug = request.user.teaching.first().slug
        else:
            self.course_slug = 'UNSET'
        return super(ProfileView, self).dispatch(request, *args, **kwargs)

    def get_context_data(self, user_limited_form, **kwargs):
        context = super(ProfileView, self).get_context_data(**kwargs)
        context.update({
            'user_limited_form': user_limited_form,
        })
        return context

    def get(self, request, *args, **kwargs):
        user = request.user
        user_limited_form = UserLimitedForm(instance=user)
        return render(
            request, 'user/profile.html',
            self.get_context_data(user_limited_form),
        )

    def post(self, request, *args, **kwargs):
        user = request.user
        user_limited_form = UserLimitedForm(request.POST, instance=user)
        if user_limited_form.is_valid():
            user_limited_form.save()
            messages.success(request, _('Profile updated.'))
        else:
            messages.error(request, _('Please correct the error below.'))

        return render(
            request, 'user/profile.html',
            self.get_context_data(user_limited_form)
        )
